#pragma once
#include "Simulation.h"
#include "GUI.h"
#include "timer.h"

#undef  LoadImage

//#define CAPTURE_FRAME

 GUI gui;
 Simulation sim;
 Timer timer;
 float elapsed = 0.0f;
 float delta_time;
 bool motion_on = true;

 int step = 0;

 unsigned char *pixel_data;

 void funcIdle() {
	 
	 elapsed += (delta_time = timer.GetDeltaTimeSeconds());

	 if (elapsed > 0.08f) {			// 1 frame
		 motion_on = true;
		 elapsed -= 0.08f;


		 // capture code here
#ifdef CAPTURE_FRAME
		 glReadPixels(0, 0, gui.width, gui.height, GL_RGB, GL_UNSIGNED_BYTE, pixel_data);

		 bitmap_image temp(gui.width, gui.height);
		 

		 std::copy(pixel_data, pixel_data + gui.width * gui.height * 3, temp.row(0));
		 temp.bgr_to_rgb();
		 //temp.reverse();
		 temp.vertical_flip();
		 //printf("captured.\n");
		 char temp_str[255];
		 sprintf_s(temp_str, 255, "capture\\___opengl_capture - %d.bmp", ++step);
		 temp.save_image(temp_str);
#endif
	 }

 }

void ShowMagnet(){

	sim.DoDisplay();
	
	


}//showMagnet


void funcMouse(int button, int state, int x, int y){


	if (sim.isSimulationNow()) return;
	Vector2 mgPos;
	bool clickMagnet;
	if(x < gui.width){
		mgPos = Vector2((float)x/gui.width,(float)y/gui.height) * 10.f;

		clickMagnet = gui.FindMagnet(mgPos);
	}

	if(y > gui.height && button == GLUT_LEFT_BUTTON){		// slidebar drag
		printf("slidebar click!\n");
		switch (state)
		{
		case GLUT_DOWN:
			gui.ControlSlide(x,y - gui.height, gui.width, gui.width/5, false);
			break;

		case GLUT_UP:
			gui.ControlSlide(x,y - gui.height, gui.width, gui.width/5, true);

			if (gui.selected_mo) gui.DelMagnet();

			gui.AddMagnet();
			sim.m_particleSystem->ResetMagnet();
			
			break;

		default:
			break;
		}
		
		return ;
	}
	else if(x > gui.width && button == GLUT_LEFT_BUTTON && !gui.dir_x){
		switch (state){
		case GLUT_DOWN:
			gui.ControlSlide(x - gui.width,y, gui.width/4 + 50, gui.height, false);
			break;

		case GLUT_UP:
			if(gui.ControlSlide(x - gui.width,y, gui.width/4 + 50, gui.height, true)){

		
			if (gui.selected_mo) gui.DelMagnet();

			gui.AddMagnet();
			sim.m_particleSystem->ResetMagnet();
			}//if(slidebar)
			break;

		default:
			break;
		}}

	else
	switch(button){

#pragma region GLUT_LEFT_BUTTON
	case GLUT_LEFT_BUTTON:

		switch(state){

		case GLUT_DOWN:
			if(clickMagnet){
				gui.ModeMove  = true;
				gui.moveStart = mgPos;
				gui.FindMagnet(mgPos);
				//gui.MoveMagnet(mgPos);

				return;

			}//if(Magnetmove mode)


			if(!gui.selectMagnet){
				printf("creating magnet\n");
				gui.selectMagnet = true;
				gui.start = Vector2((float)x/gui.width,(float)y/gui.height);
			
			}//if(false)

			break;
		//	//GLUT_DOWN

		case GLUT_UP:
			gui.ModeMove  = false;
		
			if(gui.selectMagnet){
				gui.selectMagnet = false;
				gui.end = Vector2((float)x/gui.width,(float)y/gui.height);
				

				gui.AddMagnet();
				sim.m_particleSystem->ResetMagnet();

			}//if(true)

			break;
		//	//GLUT_UP



		}//switch(state)


		break;
		//GLUT_LEFT_BUTTON
#pragma endregion GLUT_LEFT_BUTTON


#pragma region GLUT_RIGHT_BUTTON
	case GLUT_RIGHT_BUTTON:		// mouse right-button-drag is rotation

		switch (state) 
		{

		case GLUT_DOWN:

			if (!gui.ModeRotate) {
				gui.ModeRotate = true;
				gui.rotateStart = mgPos;
			}
			break;

		case GLUT_UP:

			if (gui.ModeRotate)
				gui.ModeRotate = false;

			break;

		default:
			break;
		}
		


		break;
		//GLUT_RIGHT_BUTTON
#pragma endregion GLUT_RIGHT_BUTTON


		/*
	case GLUT_MIDDLE_BUTTON:

		switch (state) 
		{

		case GLUT_DOWN:

			if (!gui.ModeMove) {
				gui.ModeMove = true;
				gui.FindMagnet(Vector2((float)x/gui.width,(float)y/gui.height) * 10.f);
				//gui.rotateStart = Vector2((float)x/gui.width,(float)y/gui.height) * 10.f;
			}
			break;

		case GLUT_UP:

			if (gui.ModeMove)
				gui.ModeMove = false;

			break;

		default:
			break;
		}

		break;
		//GLUT_MIDDLE_BUTTON
		*/
	}//switch(button)



}//funcMouse


void funcMotion(int x, int y){
	//elapsed += timer.GetDeltaTimeSeconds();

	//printf("%d\n",(int)gui.selected_mo);
	
	if(y > gui.height && gui.dir_x){
		gui.ControlSlide(x,y - gui.height, gui.width, gui.width/5, false);
		return ;	
	}
	else if (x > gui.width && !gui.dir_x){
		gui.ControlSlide(x-  gui.width,y, gui.width/4 + 50, gui.height, false);
		return ;	
	}

	if (motion_on) motion_on = false;
	else return;

	if (sim.isSimulationNow()) return;

	if (gui.ModeRotate) {
		gui.RotateMagnet(Vector2((float)x/gui.width, (float)y/gui.height));
		return;
	}

	if (gui.ModeMove) {
		gui.MoveMagnet(Vector2((float)x/gui.width, (float)y/gui.height));
	}

	if (gui.selectMagnet) {
		
		gui.end = Vector2((float)x/gui.width,(float)y/gui.height);
		gui.SetMagnet();
	}

	



}//funcMotion

void funcKeyboard(unsigned char key, int x, int y){

	switch(key){


	case 'q':
		exit(0);
		break;
		//quit

		//update magnet
	case 'u':
		//gui.AddMagnet();
		//sim.m_particleSystem->ResetMagnet();

		break;
		//update magnet
	case 'd':
		gui.DelMagnet();
		break;
		//delete

	case 'p':
		sim.SimulationBegin();

	
		break;
		//play

	case '+':
			
		gui.ratio += 0.05f;
		gui.SetMagnet();
		break;
		//+ ratio
	case '-':

		gui.ratio -= 0.05f;
		gui.SetMagnet();
		break;
		//- ratio

	case 'i':
		sim.InitParticle();

		break;
		//i
	case 'w':
		gui.MoveMO(true);
		break;
		//move forward

	case 's':
		gui.MoveMO(false);
		break;
		//move backward

	case 'm':

		gui.ModeMove = !gui.ModeMove;

		if(gui.ModeMove)
			printf("mode : move\n");
		else
			printf("mode : update\n");


		break;
		//move magnet



		break;

	case 'S':		// save magnet

		break;

	case 'L':		// load magnet

		break;

	}//switch(key)



}

int main(){

	bool dir = false;
	//srand((unsigned int)time(NULL));
	sim.LoadImage("_1image.bmp");
	sim.LoadOption();
	sim.Init(&gui);

	



	gui.width = sim.GetImageWidth();
	gui.height = sim.GetImageHeight();

#ifdef CAPTURE_FRAME
	pixel_data = new unsigned char[gui.width * gui.height * 3];
#endif
	printf("width : %d, height : %d \n", gui.width, gui.height + gui.width/5);
	glutInitWindowSize(gui.width + (int)(!dir) * gui.height/4 + 50, gui.height + (int)(dir) * gui.width/4);
	glutCreateWindow("Magnet Image");
	glutDisplayFunc(ShowMagnet);
	glutMouseFunc(funcMouse);
	glutKeyboardFunc(funcKeyboard);
	glutMotionFunc(funcMotion);
	glutIdleFunc(funcIdle);
	
	if(!gui.GuiInit(dir, 0.14f)){
		printf("fail to load texture\n");
		return 0;
	}//fail GuiInit
	
	
	glClearColor(1.0f, 1.f, 1.0, 1.0);           

	
	
	glutMainLoop();
	return 0;

}//int main

